# ====================以下部分代码只作开发测试用====================================
import django
import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo.settings.dev_settings')
django.setup()  # 加载django环境
# =============================================================================


from collections import OrderedDict
from copy import deepcopy

from goods.models import GoodsChannel, GoodsCategory, SKU, GoodsSpecification, SpecificationOption
from goods.models import SKUSpecification


def get_goods_channel_content():
    """
    获取商品频道内容
    :return: OrderedDict
    """
    categories = OrderedDict()  # 创建一个有序字典对象
    channels = GoodsChannel.objects.order_by(  # 获取商品频道的所有商品类型查询集，并根据group_id和sequence对查询集进行排序
        "group_id",
        "sequence"
    )
    for channel in channels:  # 遍历查询集，获取商品一级分类
        group_id = channel.group_id  # 获取当前商品类型所属分组id
        if group_id not in categories:  # 判断组id是否在有序字典中
            '''
            如果当前组id不在有序字典中，则将其添加进去
            组id"group_id"作为key，{"channels": [], "sub_cats": []}作为value
            '''
            categories[group_id] = {
                "channels": [],
                "sub_cats": []
            }
        cat1 = channel.category  # 获取当前商品类型（SPU，一级分类）
        categories[group_id]["channels"].append({
            "id": cat1.id,  # 类型id
            "name": cat1.name,  # 类型名称
            "url": channel.url  # 该类商品链接
        })  # 添加商品类型信息
        cat2s = GoodsCategory.objects.filter(parent=cat1)  # 根据当前商品类型，获取该类型下的所有二级分类数据
        for cat2 in cat2s:  # 遍历二级分类，获取二级分类下的具体商品
            cat2.sub_cats = []  # 创建一个新列表
            cat3s = GoodsCategory.objects.filter(parent=cat2)  # 获取当前二级分类下的所有商品（SKU）
            for cat3 in cat3s:  # 遍历二级分类下的每个商品，将商品添加到列表
                cat2.sub_cats.append(cat3)
            categories[group_id]["sub_cats"].append(cat2)  # 添加二级分类下的所有商品到列表
    return categories


def get_goods_and_spec(sku_id):
    """
    获取商品及其规格
    :param sku_id: 商品id
    :return:
    """
    # 当前SKU商品
    sku = SKU.objects.get(pk=sku_id)
    # 记录当前sku的选项组合
    cur_sku_spec_options = SKUSpecification.objects.filter(sku=sku).order_by("spec_id")
    cur_sku_options = []  # [1,4,7]
    for temp in cur_sku_spec_options:
        # temp是SKUSpecification中间表对象
        cur_sku_options.append(temp.option_id)
    # Goods对象(SPU商品)
    goods = sku.goods
    # 罗列出和当前sku同类的所有商品的选项和商品id的映射关系
    # {(1,4,7):1, (1,3,7):2}
    sku_options_mapping = {}
    skus = SKU.objects.filter(goods=goods)
    for temp_sku in skus:
        # temp_sku:每一个sku商品对象
        sku_spec_options = SKUSpecification.objects.filter(sku=temp_sku).order_by("spec_id")
        sku_options = []
        for temp in sku_spec_options:
            sku_options.append(temp.option_id)  # [1,4,7]
        sku_options_mapping[tuple(sku_options)] = temp_sku.id  # {(1,4,7):1}
    # specs当前页面需要渲染的所有规格
    specs = GoodsSpecification.objects.filter(goods=goods).order_by("id")
    for index, spec in enumerate(specs):
        # spec每一个规格对象
        options = SpecificationOption.objects.filter(spec=spec)
        # 每一次选项规格的时候，准备一个当前sku的选项组合列表，便于后续使用
        temp_list = deepcopy(cur_sku_options)   # [1,4,7]
        for option in options:
            # 每一个选项，动态添加一个sku_id值，来确定这个选项是否属于当前sku商品
            temp_list[index] = option.id  # [1,3,7] --> sku_id?
            option.sku_id = sku_options_mapping.get(tuple(temp_list))  # 找到对应选项组合的sku_id
        # 在每一个规格对象中动态添加一个属性spec_options来记录当前规格有哪些选项
        spec.spec_options = options
    return goods, sku, specs


from django.conf import settings
from django.template import loader


def generate_static_sku_detail_html(sku_id):
    # 分组频道参数
    categories = get_goods_channel_content()
    goods, sku, specs = get_goods_and_spec(sku_id)
    # =================模版渲染===================
    # 构建模版参数
    context = {
        'categories': categories,  # 用于构建详情页面商品频道
        'goods': goods,  # 当前sku商品的spu商品（Goods模型类）
        'sku': sku,
        'specs': specs  # 传入的是当前sku商品从属的spu拥有的规格及其选项
    }
    # 获取模版
    template = loader.get_template('detail.html')
    # 调用模版渲染函数，得出完整的html页面
    sku_html_text = template.render(context=context)
    # 写入静态文件
    file_path = os.path.join(
        settings.GENERATED_STATIC_HTML_FILES_DIR,
        'goods/' + str(sku_id) + '.html'  # goods/16.html
    )
    with open(file_path, 'w') as f:
        f.write(sku_html_text)


if __name__ == "__main__":
    for num in range(1, 17):
        generate_static_sku_detail_html(num)
